/**
 * @author  weigao<weigao@iflytek.com>
 *
 * @version 1.0.0
 */
package com.iflytek.uoamp.agent.monitor.dump;

import com.iflytek.uoamp.agent.monitor.dump.PSInfoCache.PSInfo;
import com.iflytek.uoamp.agent.monitor.dump.obj.DumpTask;

import org.apache.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

public class DumperTaskRunner implements Runnable{

	private Map<String,Dumper> threadMap = new ConcurrentHashMap<String, Dumper>();
	private SimpleDateFormat fullDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	private SimpleDateFormat dayDataFormat = new SimpleDateFormat("yyyy-MM-dd");
	
	
	private static DumperTaskRunner instance = new DumperTaskRunner();
	private DumperTaskRunner(){
		
	}
	
	public static DumperTaskRunner getInstance(){
		return instance;
	}
	
	public Map<String, Dumper> getThreadMap(){
		return threadMap;
	}
	
	/**
	 * 强制终止线程
	 * @param task_id
	 */
	@SuppressWarnings("deprecation")
	public void stopThread(String task_id){
		Dumper thread = threadMap.remove(task_id);
		if(thread!=null){
			Logger.getRootLogger().warn("WARN | try stop task thread "+task_id+" and thread instance task info is  "+thread.getTaskInfo());
//			thread.getTaskInfo().setNextRunTime();
			thread.interrupt();
		}else{
			Logger.getRootLogger().warn("WARN | try stop task thread "+task_id+" and thread instance is null ");
		}
	}
	
	/**
	 * 运行dump任务
	 * @param task
	 */
	private void runTask(PSInfo cache,DumpTask task){
		Dumper curTask = new Dumper(cache,task);
		//设置一个最大值；在当前任务的线程不运行结束时；该任务不会再运行其他的线程；
		task.setNextRunTime(Long.MAX_VALUE);
		threadMap.put(task.getTask_id()+"", curTask);
		curTask.start();
	}



	/**
	 * 返回是否需要执行dump任务
	 * @param task
	 * @param info
	 * @return
	 */
	private boolean isRun(DumpTask task,PSInfo info,boolean byNow){
		//是否到间隔时间
		if(task.getNextRunTime()!=0 && System.currentTimeMillis()<task.getNextRunTime()){
			return false;
		}

		if(byNow){
			return true;
		}

		//不需要分隔字符，先检查状态；
		if(task.getRun_stat()!=0 && task.getRun_stat()!=info.getCurStatus()){
			return false;
		}
		
		//判定时间段是否符合要求
		String[] set = task.getRun_time().split(" --- ");
		Date curTime = new Date();
		try{
			if(!set[0].contains("-")){
				String dayTime = dayDataFormat.format(curTime);
				set[0] = dayTime+" "+set[0];
				set[1] = dayTime+" "+set[1];
			}
			
			Date st = fullDataFormat.parse(set[0]);
			Date et = fullDataFormat.parse(set[1]);
			if(st.before(curTime) && et.after(curTime)){
				return true;
			}
		}catch(Exception e){
			Logger.getRootLogger().error(e.getMessage(), e);
		}
		return false;
	}

	/***
	 * 是否可以删除内存队列中的任务
	 * @param task
	 * @param info
	 * @return
	 */
	private boolean canRemove(DumpTask task,PSInfo info){
		//判定时间段是否符合要求
		String[] set = task.getRun_time().split(" --- ");
		Date curTime = new Date();
		try{
			if(!set[0].contains("-")){
				return false;
			}

			Date et = fullDataFormat.parse(set[1]);
			if(et.before(curTime)){
				return true;
			}
		}catch(Exception e){
			Logger.getRootLogger().error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 执行dumptask
	 */
	@Override
	public void run() {
		try{
			Map<String, DumpTask> tasks = DumpTaskGetter.getInstance().getTaskMap();
			if(tasks==null){
				return;
			}
			Iterator<Entry<String, DumpTask>> it = tasks.entrySet().iterator();
			while(it.hasNext()){
				Entry<String, DumpTask> entry = it.next();
				DumpTask task = entry.getValue();
				Logger.getRootLogger().info("INFO|try run task " + task);
				PSInfo info = PSInfoCache.getInstance().getPSInfo(task);
				if(info==null){
					Logger.getRootLogger().warn("ps info is null and ignore task for :"+task);
					task.setFinsh_stat(DumpTaskGetter.DUMP_FINISH_NOMONITOR);
					continue;
				}

				//立即执行的任务；立即启动
				if(task.getTask_type()== DumpTaskGetter.DUMP_TASK_TYPE_NOW){
					if(isRun(task, info,true)){
						runTask(info,task);
					}
					continue;
				}

				//非立即执行的；检查是否到达执行时间；
				if(isRun(task, info,false)){
					//只执行一次的任务；启动时从队列中移除；
					runTask(info,task);
				}
				try {
					if (canRemove(task, info)) {
						task.setFinsh_stat(DumpTaskGetter.DUMP_TIME_OVER);
					}
				}catch (Exception e){
					Logger.getRootLogger().error(e.getMessage(), e);
				}
			}
		}catch(Exception e){
			Logger.getRootLogger().error(e.getMessage(), e);
		}
	}
}
